/**
 * Copyright (C) 2013 AirChina
 *
 * @description:
 * @version:v1.0.0
 */
package com.china.itapi.common.redis;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.pool.impl.GenericObjectPool;

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.util.Hashing;
import redis.clients.util.Pool;

/**
 * @Description:
 * @author:larry
 * @Created:2013-10-28下午12:17:10
 */
public class JedisProxy implements InvocationHandler {

	private static GenericObjectPool.Config defaultConfig = null;

	// 默认超时时间
	private static final int CONN_TIMEOUT = 4000;

	private Pool pool;

	static {
		defaultConfig = new GenericObjectPool.Config();
		defaultConfig.maxActive = 20;
		defaultConfig.maxIdle = 10;
		defaultConfig.maxWait = 100;
		defaultConfig.testWhileIdle = true;
		defaultConfig.timeBetweenEvictionRunsMillis = 10 * 1000;
	}

	public JedisProxy(String... servers) {
		if (servers == null || servers.length == 0) {

		} else if (servers.length == 1) {
			String[] addr = servers[0].split(":");
			pool = new JedisPool(defaultConfig, addr[0], Integer.parseInt(addr[1]), CONN_TIMEOUT);
		} else {
			List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
			for (String server : servers) {
				String[] addr = server.split(":");
				JedisShardInfo shard = new JedisShardInfo(addr[0], Integer.parseInt(addr[1]), CONN_TIMEOUT, 1);
				shards.add(shard);
			}
			pool = new ShardedJedisPool(defaultConfig, shards, Hashing.MURMUR_HASH);
		}
	}

	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object result = null;
		Object obj = pool.getResource();
		try {
			result = method.invoke(obj, args);
			pool.returnResource(obj);
		} catch (Exception e) {
			pool.returnBrokenResource(obj);
		}
		return result;
	}
}
